package com.mcxx.modules.miniSalvation.salary.service.write;

import cn.hutool.core.date.DateUtil;
import com.mcxx.common.exception.BizException;
import com.mcxx.modules.miniSalvation.family.dao.read.FamilyMemberHistoryReadDao;
import com.mcxx.modules.miniSalvation.family.dao.read.FamilyMemberReadDao;
import com.mcxx.modules.miniSalvation.family.entity.FamilyMemberEntity;
import com.mcxx.modules.miniSalvation.family.entity.FamilyMemberHistoryEntity;
import com.mcxx.modules.miniSalvation.family.service.read.FamilyMemberHistoryReadService;
import com.mcxx.modules.miniSalvation.order.entity.OrderEntity;
import com.mcxx.modules.miniSalvation.salary.dao.read.FamilySalaryReadDao;
import com.mcxx.modules.miniSalvation.salary.dao.read.MemberSalaryReadDao;
import com.mcxx.modules.miniSalvation.salary.dao.write.FamilySalaryChangeWriteDao;
import com.mcxx.modules.miniSalvation.salary.dao.write.MemberSalaryChangeWriteDao;
import com.mcxx.modules.miniSalvation.salary.dto.MemberSalaryDTO;
import com.mcxx.modules.miniSalvation.salary.entity.FamilySalaryChangeEntity;
import com.mcxx.modules.miniSalvation.salary.entity.FamilySalaryEntity;
import com.mcxx.modules.miniSalvation.salary.entity.MemberSalaryChangeEntity;
import com.mcxx.modules.miniSalvation.salary.entity.MemberSalaryEntity;
import com.mcxx.util.CommonUtil;
import com.mcxx.util.Constant;
import com.mcxx.util.FailureCode;
import com.yinhai.ta404.core.service.BaseService;
import com.yinhai.ta404.core.transaction.annotation.TaTransactional;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Service("salaryChangeWriteService")
@TaTransactional
public class SalaryChangeWriteService extends BaseService {
    @Autowired
    private FamilySalaryChangeWriteDao familySalaryChangeWriteDAO;
    @Autowired
    private MemberSalaryChangeWriteDao memberSalaryChangeWriteDao;
    @Autowired
    private MemberSalaryReadDao memberSalaryReadDao;
    @Autowired
    private FamilySalaryReadDao familySalaryReadDao;
    @Autowired
    private FamilyMemberHistoryReadDao familyMemberHistoryReadDao;
    @Autowired
    private FamilyMemberReadDao familyMemberReadDao;



    public int insertSalaryChange(FamilySalaryEntity oldFamilySalary, List<MemberSalaryEntity> newMemberSalarys,
                                  String rescueyears, String type, OrderEntity orderEntity, String changeType) {
        FamilySalaryChangeEntity familyChangeEntity = new FamilySalaryChangeEntity();
        familyChangeEntity.setId(Constant.getUUID());
        familyChangeEntity.setOrderId(orderEntity.getOrderId());
        familyChangeEntity.setFamilyId(orderEntity.getFamilyId());
        familyChangeEntity.setStartDate(rescueyears);
        familyChangeEntity.setAreaCode(orderEntity.getAreaCode());
        familyChangeEntity.setCountyCode(orderEntity.getCountyCode());
        familyChangeEntity.setChangeBefore(oldFamilySalary.getSalaryNumber());
        familyChangeEntity.setChangeAfter(0d);
        familyChangeEntity.setChangeNumber(oldFamilySalary.getSalaryNumber());
        familyChangeEntity.setChangeType(changeType);
        familyChangeEntity.setRemark(type);
        familyChangeEntity.setChangeDate(new Date());
        familySalaryChangeWriteDAO.insertIgnoreNull(familyChangeEntity);
        List<MemberSalaryChangeEntity> memberChangeEntitys = new ArrayList<>();
        for (MemberSalaryEntity memberSalaryEntity : newMemberSalarys) {
            MemberSalaryChangeEntity memberChangeEntity = new MemberSalaryChangeEntity();
            memberChangeEntity.setId(Constant.getUUID());
            memberChangeEntity.setOrderId(orderEntity.getOrderId());
            memberChangeEntity.setFamilyId(orderEntity.getFamilyId());
            memberChangeEntity.setMemberId(memberSalaryEntity.getMemberId());
            memberChangeEntity.setStartDate(rescueyears);
            memberChangeEntity.setAreaCode(orderEntity.getAreaCode());
            memberChangeEntity.setCountyCode(orderEntity.getCountyCode());
            memberChangeEntity.setChangeBefore(memberSalaryEntity.getSalaryNumber());
            memberChangeEntity.setChangeAfter(0d);
            memberChangeEntity.setChangeNumber(memberSalaryEntity.getSalaryNumber());
            memberChangeEntity.setChangeType(changeType);
            memberChangeEntity.setRemark(type);
            memberChangeEntitys.add(memberChangeEntity);
        }
        int b = 0;
        if (CollectionUtils.isNotEmpty(memberChangeEntitys)) {
             b = memberSalaryChangeWriteDao.insertMemberSalaryChange(memberChangeEntitys);
        }
        return b;
    }


    public int insertSalaryChangeRecover(FamilySalaryEntity oldFamilySalary, List<MemberSalaryEntity> newMemberSalarys,
                                  String rescueyears, String type, OrderEntity orderEntity, String changeType) {
        FamilySalaryChangeEntity familyChangeEntity = new FamilySalaryChangeEntity();
        familyChangeEntity.setId(Constant.getUUID());
        familyChangeEntity.setOrderId(orderEntity.getOrderId());
        familyChangeEntity.setFamilyId(orderEntity.getFamilyId());
        familyChangeEntity.setStartDate(rescueyears);
        familyChangeEntity.setAreaCode(orderEntity.getAreaCode());
        familyChangeEntity.setCountyCode(orderEntity.getCountyCode());
        familyChangeEntity.setChangeBefore(0d);
        familyChangeEntity.setChangeAfter(oldFamilySalary.getSalaryNumber());
        familyChangeEntity.setChangeNumber(oldFamilySalary.getSalaryNumber());
        familyChangeEntity.setChangeType(changeType);
        familyChangeEntity.setRemark(type);
        familyChangeEntity.setChangeDate(new Date());
        familySalaryChangeWriteDAO.insertIgnoreNull(familyChangeEntity);
        List<MemberSalaryChangeEntity> memberChangeEntitys = new ArrayList<>();
        for (MemberSalaryEntity memberSalaryEntity : newMemberSalarys) {
            MemberSalaryChangeEntity memberChangeEntity = new MemberSalaryChangeEntity();
            memberChangeEntity.setId(Constant.getUUID());
            memberChangeEntity.setOrderId(orderEntity.getOrderId());
            memberChangeEntity.setFamilyId(orderEntity.getFamilyId());
            memberChangeEntity.setMemberId(memberSalaryEntity.getMemberId());
            memberChangeEntity.setStartDate(rescueyears);
            memberChangeEntity.setAreaCode(orderEntity.getAreaCode());
            memberChangeEntity.setCountyCode(orderEntity.getCountyCode());
            memberChangeEntity.setChangeBefore(0d);
            memberChangeEntity.setChangeAfter(memberSalaryEntity.getSalaryNumber());
            memberChangeEntity.setChangeNumber(memberSalaryEntity.getSalaryNumber());
            memberChangeEntity.setChangeType(changeType);
            memberChangeEntity.setRemark(type);
            memberChangeEntitys.add(memberChangeEntity);
        }
        int b = 0;
        if (CollectionUtils.isNotEmpty(memberChangeEntitys)) {
            b = memberSalaryChangeWriteDao.insertMemberSalaryChange(memberChangeEntitys);
        }
        return b;
    }


    public void insertSalaryChange(OrderEntity orderEntity, String rescueyears,String type,String changeType) {
        int rows = 0;
        FamilySalaryEntity oldFamilySalary = familySalaryReadDao.getFamilySumSalaryByOrderId(orderEntity.getOrderId());
        FamilySalaryChangeEntity familyChangeEntity = new FamilySalaryChangeEntity();
        familyChangeEntity.setId(Constant.getUUID());
        familyChangeEntity.setOrderId(orderEntity.getOrderId());
        familyChangeEntity.setFamilyId(orderEntity.getFamilyId());
        familyChangeEntity.setStartDate(rescueyears);
        familyChangeEntity.setAreaCode(orderEntity.getAreaCode());
        familyChangeEntity.setCountyCode(orderEntity.getCountyCode());
        familyChangeEntity.setChangeBefore(oldFamilySalary.getSalaryNumber());
        familyChangeEntity.setChangeAfter(0d);
        familyChangeEntity.setChangeNumber(oldFamilySalary.getSalaryNumber());
        familyChangeEntity.setChangeType(changeType);
        familyChangeEntity.setChangeDate(DateUtil.date());
        familyChangeEntity.setRemark(type);
        rows = familySalaryChangeWriteDAO.insertIgnoreNull(familyChangeEntity);
        if (rows < 1) {
            throw new BizException(FailureCode.ERR_9999);
        }
        List<MemberSalaryChangeEntity> memberChangeEntitys = new ArrayList<>();
        List<MemberSalaryEntity> memberSalarys = memberSalaryReadDao.queryMemberSalaryByOrderId(orderEntity.getOrderId());

        if (memberSalarys == null || memberSalarys.size() == 0) {
            throw new BizException(FailureCode.ERR_1000023);
        }

        for (MemberSalaryEntity memberSalaryEntity: memberSalarys) {
            MemberSalaryChangeEntity memberChangeEntity = new MemberSalaryChangeEntity();
            memberChangeEntity.setId(Constant.getUUID());
            memberChangeEntity.setOrderId(orderEntity.getOrderId());
            memberChangeEntity.setFamilyId(orderEntity.getFamilyId());
            memberChangeEntity.setMemberId(memberSalaryEntity.getMemberId());
            memberChangeEntity.setStartDate(rescueyears);
            memberChangeEntity.setAreaCode(orderEntity.getAreaCode());
            memberChangeEntity.setCountyCode(orderEntity.getCountyCode());
            memberChangeEntity.setChangeBefore(memberSalaryEntity.getSalaryNumber());
            memberChangeEntity.setChangeAfter(0d);
            memberChangeEntity.setChangeNumber(memberSalaryEntity.getSalaryNumber());
            memberChangeEntity.setChangeType(changeType);
            memberChangeEntity.setRemark(type);
            memberChangeEntitys.add(memberChangeEntity);
        }

        rows = memberSalaryChangeWriteDao.insertMemberSalaryChange(memberChangeEntitys);
        if (rows < 1) {
            throw new BizException(FailureCode.ERR_9999);
        }
    }

    public void houseHoldCancelSalaryChange(OrderEntity orderEntity, String rescueyears,String type,String changeType) {
        int rows = 0;
        FamilySalaryEntity oldFamilySalary = familySalaryReadDao.getFamilySumSalaryByOrderId(orderEntity.getSourOrderId());
        FamilySalaryChangeEntity familyChangeEntity = new FamilySalaryChangeEntity();
        familyChangeEntity.setId(Constant.getUUID());
        familyChangeEntity.setOrderId(orderEntity.getOrderId());
        familyChangeEntity.setFamilyId(orderEntity.getFamilyId());
        familyChangeEntity.setStartDate(rescueyears);
        familyChangeEntity.setAreaCode(orderEntity.getAreaCode());
        familyChangeEntity.setCountyCode(orderEntity.getCountyCode());
        familyChangeEntity.setChangeBefore(oldFamilySalary.getSalaryNumber());
        familyChangeEntity.setChangeAfter(0d);
        familyChangeEntity.setChangeNumber(oldFamilySalary.getSalaryNumber());
        familyChangeEntity.setChangeType(changeType);
        familyChangeEntity.setChangeDate(DateUtil.date());
        familyChangeEntity.setRemark(type);
        rows = familySalaryChangeWriteDAO.insertIgnoreNull(familyChangeEntity);
        if (rows < 1) {
            throw new BizException(FailureCode.ERR_9999);
        }
        List<MemberSalaryChangeEntity> memberChangeEntitys = new ArrayList<>();
        List<MemberSalaryEntity> memberSalarys = memberSalaryReadDao.queryMemberSalaryByOrderId(orderEntity.getSourOrderId());

        if (memberSalarys == null || memberSalarys.size() == 0) {
            throw new BizException(FailureCode.ERR_1000023);
        }
        for (MemberSalaryEntity memberSalaryEntity: memberSalarys) {

//            if(Constant.CareFeeType.CARE_CODE.equals(memberSalaryEntity.getItemType())){


            MemberSalaryChangeEntity memberChangeEntity = new MemberSalaryChangeEntity();
            memberChangeEntity.setId(Constant.getUUID());
            memberChangeEntity.setOrderId(orderEntity.getOrderId());
            memberChangeEntity.setFamilyId(orderEntity.getFamilyId());
            memberChangeEntity.setMemberId(memberSalaryEntity.getMemberId());
            memberChangeEntity.setStartDate(rescueyears);
            memberChangeEntity.setAreaCode(orderEntity.getAreaCode());
            memberChangeEntity.setCountyCode(orderEntity.getCountyCode());
            memberChangeEntity.setChangeBefore(memberSalaryEntity.getSalaryNumber());
            memberChangeEntity.setChangeAfter(0d);
            memberChangeEntity.setChangeNumber(memberSalaryEntity.getSalaryNumber());
            memberChangeEntity.setChangeType(changeType);
            memberChangeEntity.setRemark(type);
            memberChangeEntitys.add(memberChangeEntity);
        }

        rows = memberSalaryChangeWriteDao.insertMemberSalaryChange(memberChangeEntitys);
        if (rows < 1) {
            throw new BizException(FailureCode.ERR_9999);
        }
    }

    public int insertByNew(String rescueYears, String orderId, String familyId, String areaCode, String countyCode) {

        List<MemberSalaryDTO> memberSalaryDTOList = memberSalaryReadDao.listMemberSalary(familyId, orderId, "1");

        double salaryNumber = familySalaryReadDao.getFamilySalary(orderId, familyId);



        FamilySalaryChangeEntity familyChangeEntity = new FamilySalaryChangeEntity();
        familyChangeEntity.setId(Constant.getUUID());
        familyChangeEntity.setOrderId(orderId);
        familyChangeEntity.setFamilyId(familyId);
        familyChangeEntity.setStartDate(rescueYears);
        familyChangeEntity.setAreaCode(areaCode);
        familyChangeEntity.setCountyCode(countyCode);
        familyChangeEntity.setChangeBefore(0d);
        familyChangeEntity.setChangeAfter(salaryNumber);
        familyChangeEntity.setChangeNumber(salaryNumber);
        familyChangeEntity.setChangeDate(new Date());
        familyChangeEntity.setChangeType(Constant.SalaryChangeType.CHANGE_NEW);

        int rst = familySalaryChangeWriteDAO.insertIgnoreNull(familyChangeEntity);
        if (rst <= 0) {
            throw new BizException("-1", "添加家庭待遇变化异常");
        }


        List<MemberSalaryChangeEntity> memberChangeEntityList = new ArrayList<>();
        for (MemberSalaryDTO memberSalaryDTO : memberSalaryDTOList) {
            MemberSalaryChangeEntity memberChangeEntity = new MemberSalaryChangeEntity();
            memberChangeEntity.setId(Constant.getUUID());
            memberChangeEntity.setOrderId(orderId);
            memberChangeEntity.setFamilyId(familyId);
            memberChangeEntity.setStartDate(rescueYears);
            memberChangeEntity.setAreaCode(areaCode);
            memberChangeEntity.setCountyCode(countyCode);
            memberChangeEntity.setChangeType(Constant.SalaryChangeType.CHANGE_NEW);
            memberChangeEntity.setChangeBefore(0d);

            memberChangeEntity.setChangeNumber(memberSalaryDTO.getSalaryNumber());
            memberChangeEntity.setChangeAfter(memberSalaryDTO.getSalaryNumber());
            memberChangeEntity.setMemberId(memberSalaryDTO.getMemberId());

            memberChangeEntityList.add(memberChangeEntity);
        }
        rst = memberSalaryChangeWriteDao.insertMemberSalaryChange(memberChangeEntityList);
        if (rst <= 0) {
            throw new BizException("-1", "添加家庭待遇变化异常");
        }
        return 1;
    }

    public int insertByRecheck(String rescueYears,String orderId,String sourceOrderId,String familyId, String areaCode, String countyCode) {

        double oldFamilySalary = familySalaryReadDao.getFamilySalary(sourceOrderId, familyId);

        double salaryNumber = familySalaryReadDao.getFamilySalary(orderId, familyId);
        double changNum = salaryNumber-oldFamilySalary;

        List<MemberSalaryDTO> oldMemberSalaryDTOList = memberSalaryReadDao.selectMemberSalary(familyId, sourceOrderId);

        List<MemberSalaryDTO> memberSalaryDTOList = memberSalaryReadDao.listMemberSalary(familyId, orderId, "1");


        FamilySalaryChangeEntity familyChangeEntity = new FamilySalaryChangeEntity();
        familyChangeEntity.setId(Constant.getUUID());
        familyChangeEntity.setOrderId(orderId);
        familyChangeEntity.setFamilyId(familyId);
        familyChangeEntity.setStartDate(rescueYears);
        familyChangeEntity.setAreaCode(areaCode);
        familyChangeEntity.setCountyCode(countyCode);
        familyChangeEntity.setChangeBefore(oldFamilySalary);
        familyChangeEntity.setChangeAfter(salaryNumber);
        familyChangeEntity.setChangeNumber(Math.abs(changNum));
        familyChangeEntity.setChangeDate(new Date());
        familyChangeEntity.setChangeType(changNum==0?Constant.SalaryChangeType.CHANGE_NO:changNum>0?Constant.SalaryChangeType.CHANGE_ADD:Constant.SalaryChangeType.CHANGE_REDUCE);

        int rst = familySalaryChangeWriteDAO.insertIgnoreNull(familyChangeEntity);
        if (rst <= 0) {
            throw new BizException("-1", "添加家庭待遇变化异常");
        }


        List<MemberSalaryChangeEntity> memberChangeEntityList = new ArrayList<>();
        for (MemberSalaryDTO memberSalaryDTO : memberSalaryDTOList) {
            MemberSalaryDTO oldMemberSalaryDTO = null;
            Optional<MemberSalaryDTO> memberOption  = oldMemberSalaryDTOList.stream().filter(o->memberSalaryDTO.getMemberId().equals(o.getMemberId())).findFirst();
            if(memberOption.isPresent()){
                oldMemberSalaryDTO = memberOption.get();
            }
            MemberSalaryChangeEntity memberChangeEntity = new MemberSalaryChangeEntity();
            memberChangeEntity.setId(Constant.getUUID());
            memberChangeEntity.setOrderId(orderId);
            memberChangeEntity.setFamilyId(familyId);
            memberChangeEntity.setStartDate(rescueYears);
            memberChangeEntity.setAreaCode(areaCode);
            memberChangeEntity.setCountyCode(countyCode);


            FamilyMemberHistoryEntity familyMemberHistoryEntity = familyMemberHistoryReadDao.getBySourOrderId(memberSalaryDTO.getMemberId(),sourceOrderId);

            if (null != familyMemberHistoryEntity && Constant.PeopleState.SUSPEND_STATE.equals(familyMemberHistoryEntity.getState())) {
                memberChangeEntity.setChangeType(Constant.SalaryChangeType.CANCEL_SUSPEND);
            }else{
                memberChangeEntity.setChangeType(Constant.SalaryChangeType.CHANGE_NEW);
            }

            memberChangeEntity.setChangeBefore(0d);
            memberChangeEntity.setChangeNumber(memberSalaryDTO.getSalaryNumber());
            memberChangeEntity.setChangeAfter(memberSalaryDTO.getSalaryNumber());
            memberChangeEntity.setMemberId(memberSalaryDTO.getMemberId());

            if(!CommonUtil.invalidArgs(oldMemberSalaryDTO)){
                double changeBefore = oldMemberSalaryDTO.getSalaryNumber();
                memberChangeEntity.setChangeBefore(changeBefore);
                double change = memberSalaryDTO.getSalaryNumber()-oldMemberSalaryDTO.getSalaryNumber();
                memberChangeEntity.setChangeNumber(Math.abs(change));
                memberChangeEntity.setChangeType(change==0?Constant.SalaryChangeType.CHANGE_NO:change>0?Constant.SalaryChangeType.CHANGE_ADD:Constant.SalaryChangeType.CHANGE_REDUCE);
            }
            memberChangeEntityList.add(memberChangeEntity);
        }

        for(MemberSalaryDTO memberSalaryDTO:oldMemberSalaryDTOList){
            Optional<MemberSalaryDTO> first = memberSalaryDTOList.stream().filter(o -> memberSalaryDTO.getMemberId().equals(o.getMemberId())).findFirst();
            if(!first.isPresent()){
                MemberSalaryChangeEntity memberChangeEntity = new MemberSalaryChangeEntity();
                memberChangeEntity.setId(Constant.getUUID());
                memberChangeEntity.setOrderId(orderId);
                memberChangeEntity.setFamilyId(familyId);
                memberChangeEntity.setStartDate(rescueYears);
                memberChangeEntity.setAreaCode(areaCode);
                memberChangeEntity.setCountyCode(countyCode);

                FamilyMemberEntity memberEntity = familyMemberReadDao.getById(memberSalaryDTO.getMemberId());
                if (null != memberEntity && Constant.PeopleState.SUSPEND_STATE.equals(memberEntity.getState())) {
                    memberChangeEntity.setChangeType(Constant.SalaryChangeType.CHANGE_SUSPEND);
                }else{
                    memberChangeEntity.setChangeType(Constant.SalaryChangeType.CHANGE_EXPIRE);
                }

                memberChangeEntity.setChangeBefore(memberSalaryDTO.getSalaryNumber());
                memberChangeEntity.setChangeNumber(memberSalaryDTO.getSalaryNumber());
                memberChangeEntity.setChangeAfter(0d);
                memberChangeEntity.setMemberId(memberSalaryDTO.getMemberId());
                memberChangeEntityList.add(memberChangeEntity);
            }
        }
        rst = memberSalaryChangeWriteDao.insertMemberSalaryChange(memberChangeEntityList);
        if (rst <= 0) {
            throw new BizException("-1", "添加家庭待遇变化异常");
        }
        return 1;
    }

    public void deleteByOrderId(String orderId) {
        int rows1,rows2;
        rows1 = familySalaryChangeWriteDAO.deleteByOrderId(orderId);
        rows2 = memberSalaryChangeWriteDao.deleteByOrderId(orderId);
        if (rows1 == 0 || rows2 == 0) {
            throw new BizException(FailureCode.ERR_10003);
        }
    }


    public int batchInsertMemberSalaryChange(List<MemberSalaryChangeEntity> paramList) {
        return memberSalaryChangeWriteDao.insertMemberSalaryChange(paramList);
    }


    public void batchDeleteByOrderId(List<String> orderIdList) {
        int rows1,rows2;
        rows1 = familySalaryChangeWriteDAO.batchDeleteByOrderId(orderIdList);
        rows2 = memberSalaryChangeWriteDao.batchDeleteByOrderId(orderIdList);
        if (rows1 == 0 || rows2 == 0) {
            throw new BizException(FailureCode.ERR_10003);
        }
    }


    public void deleteBackByOrderId(String orderId) {
        familySalaryChangeWriteDAO.deleteByOrderId(orderId);
        memberSalaryChangeWriteDao.deleteByOrderId(orderId);
    }
}
